package com.common.atom.seal.util;

import com.common.atom.seal.param.SquareSealParam;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

/**
 * description: SquareSealUtil <br>
 * date: 2023/4/14  <br>
 * author: zss <br>
 * version: 1.0.0 <br>
 */
public class SquareSealUtil {

    /**
     * 画方形印章
     */
    public static byte[] drawSquareSeal(SquareSealParam seal) throws IOException {
        String text = seal.getText();
        // 计算文本矩形
        int[] cal = cal(text.length());

        int imageWidth = seal.getDiameter();
        int imageHeight = seal.getDiameter();
        //默认40 mm
        int borderSize = (int) (seal.getBorderSize() * 25.4 / 72);
        int margin = 20;

        BufferedImage bufferedImage = new BufferedImage(imageWidth, imageHeight, BufferedImage.TYPE_INT_ARGB_PRE);
        Graphics2D g2d = bufferedImage.createGraphics();
        // 设置颜色
        Color color = ColorUtils.getColor(seal.getColor(), seal.getAlpha());
        g2d.setColor(color);
        // 消除画图锯齿
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 消除文字锯齿
        g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
        // 画矩形框
        if (seal.getFrame() == null || seal.getFrame() == 1) {
            drawRectangle(imageWidth, imageHeight, borderSize, g2d);
        }

        int fontSize = (imageHeight - margin) / cal[0] - borderSize - margin;
        Font font = ImageUtils.CreateFont(seal.getFontType(), fontSize);

        g2d.setFont(font);

        drawText(text, cal, imageWidth, imageHeight, borderSize, margin, font, g2d);

        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        ImageIO.write(bufferedImage, "png", outputStream);
        return outputStream.toByteArray();
    }

    /**
     * 画文本
     */
    private static void drawText(String text, int[] cal, int imageWidth, int imageHeight, int borderSize, int margin, Font font, Graphics2D g2d) {
        FontMetrics fontMetrics = g2d.getFontMetrics(font);
        for (int a = 0; a < cal[0]; a++) {
            String tempText;
            int start = a * cal[1];
            if (a != cal[0] - 1) {
                tempText = text.substring(start, cal[1] + start);
            } else {
                tempText = text.substring(start);
            }

            int x = (cal[0] - a - 1) * (imageWidth - margin) / cal[0] + margin;
            for (int b = 0; b < tempText.length(); b++) {
                char wordChar = tempText.charAt(b);
                String wordText = String.valueOf(wordChar);
                int y = b * (imageHeight - borderSize * 2) / tempText.length() +
                        ((imageHeight - borderSize * 2) / tempText.length() - fontMetrics.getHeight()) / 2 +
                        fontMetrics.getAscent() + (borderSize + margin) / 4;
                if (isEnglish(wordText) || chineseSymbol(wordChar)) {
                    g2d.drawString(wordText, x + 4 + fontMetrics.getHeight() / 4, y);
                } else {
                    g2d.drawString(wordText, x + 4, y);
                }
            }
        }
    }

    /**
     * 判断英文
     */
    private static boolean isEnglish(String p) {
        byte[] bytes = p.getBytes();
        int i = bytes.length;
        int j = p.length();
        return i == j;
    }

    /**
     * 判断是否中文符号
     */
    private static boolean chineseSymbol(char c) {
        Character.UnicodeBlock ub = Character.UnicodeBlock.of(c);
        return ub == Character.UnicodeBlock.GENERAL_PUNCTUATION
                || ub == Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION
                || ub == Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
                || ub == Character.UnicodeBlock.CJK_COMPATIBILITY_FORMS
                || ub == Character.UnicodeBlock.VERTICAL_FORMS;
    }

    /**
     * 画方形框
     */
    private static void drawRectangle(int imageWidth, int imageHeight, int borderSize, Graphics2D g2d) {
        g2d.fillRect(0, 0, imageWidth, borderSize);
        g2d.fillRect(0, 0, borderSize, imageHeight);
        g2d.fillRect(imageWidth - borderSize, 0, borderSize, imageHeight);
        g2d.fillRect(0, imageHeight - borderSize, imageWidth, borderSize);
    }

    /**
     * 计算最大的长和宽
     */
    private static int[] cal(int a) {
        int[] cal = new int[2];
        int x = (int) Math.ceil(Math.sqrt(a));
        cal[0] = x;
        for (int y = a / x; ; y++) {
            if (x * y >= a) {
                cal[1] = y;
                break;
            }
        }
        return cal;
    }

}
